package com.xaaef.authorize.server.controller;

import com.xaaef.authorize.common.exception.OAuth2Exception;
import com.xaaef.authorize.common.util.JsonResult;
import com.xaaef.authorize.common.util.JsonUtils;
import com.xaaef.authorize.server.params.*;
import com.xaaef.authorize.server.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

/**
 * All rights Reserved, Designed By www.xaaef.com
 * <p>
 * 授权码模式 控制器
 * </p>
 *
 * @author Wang Chen Chen<932560435@qq.com>
 * @version 1.0.0
 * @date 2020/7/2314:02
 */


@Slf4j
@Controller
@AllArgsConstructor
public class CodeController {

    private CodeAuthorizeService codeAuthorizeService;

    /**
     * 授权码模式，1.第三方应用，请求获取用户信息。在此校验客户端是否正确
     *
     * @author Wang Chen Chen<932560435@qq.com>
     * @date 2020/7/23 14:08
     */
    @GetMapping("code")
    public ModelAndView getCode(@Validated GetCodeModeParam param, BindingResult br) {
        var result = new ModelAndView("paramError");
        if (br.hasErrors()) {
            result.addObject("errors", br.getFieldErrors());
        }
        log.debug("getCode param: {}", JsonUtils.toJson(param));
        try {
            // 校验客户端是否存在！
            // 一个随机的 授权ID，由系统随机生成，绑定给每个前来授权的第三方应用，
            // 主要用来连贯用户一些列操作！
            String codeId = codeAuthorizeService.validateClient(param);
            result.addObject("codeId", codeId);

            result.setViewName("login");
        } catch (OAuth2Exception e) {
            var oauth2Errors = List.of(
                    new FieldError("OAuth2Exception", String.valueOf(e.getStatus()), e.getMessage())
            );
            result.addObject("errors", oauth2Errors);
        }
        return result;
    }

    /**
     * 授权码模式，第二步，用户登录
     *
     * @author Wang Chen Chen<932560435@qq.com>
     * @date 2020/7/23 14:08
     */
    @PostMapping("login")
    @ResponseBody
    public JsonResult<String> login(@RequestBody @Validated LoginParam param, BindingResult br) {
        if (br.hasErrors()) {
            return JsonResult.fail(br.getFieldError().getDefaultMessage());
        }
        try {
            // 回调 URL
            String redirectUri = codeAuthorizeService.login(param);
            // 让前端页面去跳转到 第三方应用
            return JsonResult.success(null, redirectUri);
        } catch (OAuth2Exception e) {
            return JsonResult.error(e.getStatus(), e.getMessage());
        }
    }


    /**
     * 授权码模式，第三步，第三方应用通过 code 来换取 access_token
     *
     * @author Wang Chen Chen<932560435@qq.com>
     * @date 2020/7/23 14:08
     */
    @PostMapping("access_token")
    @ResponseBody
    public JsonResult<String> accessToken(@RequestBody @Validated AuthorizationCodeModeParam param, BindingResult br) {
        if (br.hasErrors()) {
            return JsonResult.fail(br.getFieldError().getDefaultMessage());
        }
        log.debug("accessToken param: {}", JsonUtils.toJson(param));
        try {
            var token = codeAuthorizeService.authorize(param);
            return JsonResult.success(token);
        } catch (OAuth2Exception e) {
            return JsonResult.error(e.getStatus(), e.getMessage());
        }
    }

}
